package com.zenithmind.news.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.news.mapper.UserBehaviorMapper;
import com.zenithmind.news.pojo.entity.UserBehavior;
import com.zenithmind.news.service.UserBehaviorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户行为服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserBehaviorServiceImpl extends ServiceImpl<UserBehaviorMapper, UserBehavior> implements UserBehaviorService {

    private final UserBehaviorMapper userBehaviorMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final String USER_BEHAVIOR_CACHE_KEY = "user:behavior:";
    private static final String NEWS_BEHAVIOR_CACHE_KEY = "news:behavior:";

    @Override
    public Boolean recordBehavior(String userId, String newsId, Integer behaviorType, 
                                 String behaviorValue, Double score) {
        try {
            UserBehavior behavior = new UserBehavior();
            behavior.setUserId(userId);
            behavior.setNewsId(newsId);
            behavior.setBehaviorType(behaviorType);
            behavior.setBehaviorValue(behaviorValue);
            behavior.setScore(score);
            behavior.setBehaviorTime(LocalDateTime.now());
            
            // 设置设备信息等（这里简化处理）
            behavior.setDeviceType(1); // PC
            behavior.setIpAddress("127.0.0.1");
            behavior.setLocation("未知");
            
            boolean saved = save(behavior);
            
            if (saved) {
                // 更新缓存
                updateBehaviorCache(userId, newsId, behaviorType);
                log.debug("记录用户行为：用户ID={}, 新闻ID={}, 行为类型={}", userId, newsId, behaviorType);
            }
            
            return saved;
        } catch (Exception e) {
            log.error("记录用户行为失败", e);
            return false;
        }
    }

    @Override
    public List<UserBehavior> getUserBehaviorHistory(String userId, Integer behaviorType, Integer limit) {
        LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserBehavior::getUserId, userId);
        if (behaviorType != null) {
            wrapper.eq(UserBehavior::getBehaviorType, behaviorType);
        }
        wrapper.orderByDesc(UserBehavior::getBehaviorTime);
        wrapper.last("LIMIT " + limit);
        
        return list(wrapper);
    }

    @Override
    public Map<String, Object> getUserPreferenceAnalysis(String userId) {
        // 先从缓存获取
        String cacheKey = USER_BEHAVIOR_CACHE_KEY + "preference:" + userId;
        Map<String, Object> cachedResult = (Map<String, Object>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null) {
            return cachedResult;
        }

        Map<String, Object> result = new HashMap<>();
        
        // 获取用户最近30天的行为数据
        LocalDateTime startTime = LocalDateTime.now().minusDays(30);
        LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserBehavior::getUserId, userId);
        wrapper.ge(UserBehavior::getBehaviorTime, startTime);
        
        List<UserBehavior> behaviors = list(wrapper);
        
        // 分析行为类型偏好
        Map<Integer, Long> behaviorTypeCount = new HashMap<>();
        Map<Integer, Double> behaviorTypeScore = new HashMap<>();
        
        for (UserBehavior behavior : behaviors) {
            Integer type = behavior.getBehaviorType();
            behaviorTypeCount.merge(type, 1L, Long::sum);
            behaviorTypeScore.merge(type, behavior.getScore(), Double::sum);
        }
        
        result.put("behaviorTypeCount", behaviorTypeCount);
        result.put("behaviorTypeScore", behaviorTypeScore);
        result.put("totalBehaviors", behaviors.size());
        result.put("analysisTime", LocalDateTime.now());
        
        // 缓存结果
        redisTemplate.opsForValue().set(cacheKey, result, 1, TimeUnit.HOURS);
        
        return result;
    }

    @Override
    public Map<String, Long> getNewsBehaviorStatistics(String newsId) {
        // 先从缓存获取
        String cacheKey = NEWS_BEHAVIOR_CACHE_KEY + newsId;
        Map<String, Long> cachedResult = (Map<String, Long>) redisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null) {
            return cachedResult;
        }

        Map<String, Long> result = new HashMap<>();
        
        LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserBehavior::getNewsId, newsId);
        
        List<UserBehavior> behaviors = list(wrapper);
        
        // 统计各种行为类型的数量
        for (UserBehavior behavior : behaviors) {
            String behaviorName = getBehaviorTypeName(behavior.getBehaviorType());
            result.merge(behaviorName, 1L, Long::sum);
        }
        
        // 缓存结果
        redisTemplate.opsForValue().set(cacheKey, result, 30, TimeUnit.MINUTES);
        
        return result;
    }

    @Override
    public Double getUserActivityScore(String userId, LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserBehavior::getUserId, userId);
        wrapper.between(UserBehavior::getBehaviorTime, startTime, endTime);
        
        List<UserBehavior> behaviors = list(wrapper);
        
        if (behaviors.isEmpty()) {
            return 0.0;
        }
        
        // 计算活跃度评分
        double totalScore = behaviors.stream()
                .mapToDouble(UserBehavior::getScore)
                .sum();
        
        // 考虑行为频率
        long days = java.time.temporal.ChronoUnit.DAYS.between(startTime, endTime);
        if (days == 0) days = 1;
        
        double frequencyScore = (double) behaviors.size() / days;
        
        return totalScore + frequencyScore * 10;
    }

    @Override
    public Long cleanExpiredBehaviors(Integer days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);
        
        LambdaQueryWrapper<UserBehavior> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(UserBehavior::getBehaviorTime, expireTime);
        
        long count = count(wrapper);
        boolean removed = remove(wrapper);
        
        if (removed) {
            log.info("清理过期用户行为数据：{} 条", count);
        }
        
        return count;
    }

    /**
     * 更新行为缓存
     */
    private void updateBehaviorCache(String userId, String newsId, Integer behaviorType) {
        // 清除相关缓存
        String userCacheKey = USER_BEHAVIOR_CACHE_KEY + "preference:" + userId;
        String newsCacheKey = NEWS_BEHAVIOR_CACHE_KEY + newsId;
        
        redisTemplate.delete(userCacheKey);
        redisTemplate.delete(newsCacheKey);
    }

    /**
     * 获取行为类型名称
     */
    private String getBehaviorTypeName(Integer behaviorType) {
        return switch (behaviorType) {
            case 1 -> "view";
            case 2 -> "like";
            case 3 -> "favorite";
            case 4 -> "share";
            case 5 -> "comment";
            case 6 -> "search";
            default -> "unknown";
        };
    }
}
